
#include "./fiber-pool.h"
#include "./string.h"

namespace fasmio { namespace common {

FiberPool::FiberPool(ILogger* logger, const char* name) :
    logger_(logger),
    mlogger_(logger, "FiberPool"),
    quit_event_(fiber_env::NewEvent(false)),
    fiber_pool_name_(),
    fibers_()
{
    if (nullptr != name)
        fiber_pool_name_ = name;
    else
        fiber_pool_name_ = format("Pool #%08X", static_cast<void*>(this));
}

FiberPool::~FiberPool()
{
}

bool FiberPool::Start(unsigned int fiber_count)
{
    if (fiber_count == 0)
        return false;

    quit_event_->Reset();
    for (unsigned i=0; i<fiber_count; ++i)
    {
        fiber_env::Fiber* fiber = fiber_env::CreateFiber(
                    Worker, static_cast<void*>(this), fiber_pool_name_.c_str());
        if (nullptr == fiber)
            return false;

        fibers_.push_back(fiber);
    }

    return true;
}

void FiberPool::Stop()
{
    quit_event_->Set();
    for (fibers_t::iterator iter = fibers_.begin();
        iter != fibers_.end(); ++iter)
    {
        fiber_env::Fiber* fiber = *iter;
        fiber->Join();
    }
    fibers_.clear();
}

int FiberPool::Worker(void* arg)
{
    FiberPool* pool = reinterpret_cast<FiberPool*>(arg);
    if (pool != nullptr)
        pool->Worker();
    return 0;
}

}}  // namespace fasmio::common

